home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-12-03 | 100.4 KB | 2,524 lines | [TEXT/R*ch] |
- Mac Programming Frequently Asked Questions Answer Sheet
- Last update: 30 September 1995
-
- Please download a copy of this answer sheet and search it before
- you post to the 'net, to help reduce bandwidth. This sheet is
- available in two formats for your online viewing enjoyment:
- plaintext (ftp://ftp.best.com/pub/ckt/csmpFAQ.txt) and
- HTML (http://www.best.com/~ckt/csmpFAQ.html).
-
- Obsolete questions which have been removed from the FAQ proper
- are archived seperately. (http://www.best.com/~ckt/culled.html)
-
- Send submissions, questions, suggestions, new links, and corrections
- to Chris Thomas (mailto:ckt@best.com), current caretaker of the
- FAQ. All submissions sent will be considered to be in the public
- domain unless stated otherwise (in which case they will not be
- included in this FAQ sheet).
-
- No FAQ can substitute for real documentation (some of which is
- mentioned in this FAQ). If you ask a question in comp.sys.mac.programmer
- which has a good answer in one of the important sources, you
- will probably not get an answer. (Inside Macintosh, Macintosh
- Technical Notes, and MPTA being important sources). These sources
- are available in electronic form
- (http://www.info.apple.com/dev/developerservices.html).
-
- There is NO or VERY LIMITED error checking in the code examples,
- FOR BREVITY ONLY. You should make sure you ALWAYS check ALL
- return codes, and handle any that you are not prepared to deal
- with appropriately.
-
- Exciting new stuff: Frameworks update! HTML->text conversion
- process still not entirely wonderful. Various link fixes.
- The usual tweaks.
-
-
-
- Topics:
- [search for *number* to find a topic quickly]
- [topics changed since last edition are marked "+"; new topics
- ">"]
-
-
- 1. +Development Tools
- getting started, tool-specific issues, frameworks
- 2. Memory
- handles & resources, large arrays
- 3. Human Interfacing
- menus, windows, events, multitasking
- 4. Files
- Mac fopen, wdrefnums, getting full pathnames
- 5. Imaging
- QuickDraw and the means to avoid it
- 6. Text
- Text editing packages, string conversion
- 7. Communications and Networking
- serial ports, TCP/IP, sockets
- 8. Interapplication Communication
- AppleEvents, OSA, Scripting, and You
- 9. Dynamic Linking & Code Resources
- the dynamics of code resources & trap patches inits
- 10. Compatibility
- gestalt & glue
- 11. Optional System Software Technology
- What else Apple will do for you.
-
- 11.1. QuickTime
- codec details and the lack thereof
- 11.2. QuickDraw 3D
- happy compilers exist in three dimensions
- 11.3. OpenDoc
- recursively searching for OpenDoc
-
- 12. Third Party Solutions
- What Apple won't do for you.
-
- 12.1. Databases & ODBC
- client/server solutions
- 12.2. Circumventing Toolbox Limitations
- foul baggage begone- List Manager replacements?
-
- 13. Dessert
- yummies the Macintosh way
- 14. >Other Answers
- no faq is an island- other sources for answers
- 15. Contributors
- registered SmartFriends(tm)
-
-
-
- *1* Development Tools
-
- 1.1) Q: What do I need to start writing Macintosh software?
-
- A: A Mac, a lot of time, and a few hundred $. Although you can
- develop software on a Classic/SE-type machine, it is not to be
- attempted by the weak of heart or stressed of time. If you're
- doing paid work and/or work for a company, a Quadra-class machine
- is a must; remember that your time costs your employer much more
- than just your salary. A PowerMac is *highly* preferable. 16
- MB is a minimum to run at all comfortably (40 MB recommended),
- and Virtual Memory (including RamDoubler) is not suited for development
- work. Similarly, if you don't have at least 80 MB free on your
- hard disk you need to buy more space. You will also need a CD-ROM
- drive.
-
- You need a development system such as CodeWarrior, MPW Pro, Symantec
- C++ 8.0 or Prograph, you need at least some of the New Inside
- Mac books (Toolbox Essentials, Files, Memory come to mind) and
- a good entry-level third-party book may help.
-
- Once you are up to speed on the general layout of the Mac and
- its toolboxes, you should call APDA and order the monthly developer
- mailing, which will give you a CD chock full of documentation,
- utilities and system software once a month. You will also, obviously,
- need a CD player. If you don't have the dough for the monthly
- mailing ($250/year) you can order a _develop_ subscription; this
- quarterly magazine ($30-$50/year) comes with a CD containing
- most Inside Mac documentation. Another good product to order
- is the MacOS SDK, which for $99 gives you a CD with every API
- in existence up to and including the 7.5 Mac Toolbox additions.
- It's somewhat redundant if you already have the Developer CD
- subscription (mailto:apda@appplelink.apple.com). Apple's Developer
- Web (http://www.info.apple.com/dev/developerservices.html) has
- almost all of the contents of the Developer CD's online.
-
- If you don't know how to program, go learn your language of choice
- BEFORE attempting a "real" Mac application. Programming is a
- discipline often requiring different thought processes than your
- normal day job. A beginning book, like Lippman: The C++ Primer,
- one of the Teach Yourself (language-of-choice) books, or the
- primers available on the CodeWarrior CD, might help.
-
- An indispensable Mac programming tool is the Macintosh Programmer's
- Toolbox Reference (MPTA), an up-to-date hypertext reference guide
- containing reference material on the New Inside Mac-documented
- portions of the Toolbox with lightning-fast look-up and mostly
- correct usage hints and code snippets. MPTA can be found on
- the Developer CD, and is also offered on a seperate $99 CD.
- Contact APDA (mailto:apda@applelink.apple.com) for further details.
-
- 1.2) Q: What is the most used Macintosh development system?
-
- A: Currently, the three most widely used are CodeWarrior (CW),
- MPW, and Symantec C++, probably in that order, though I don't
- have any statistics. The latest version of any one of these
- is adequate for Mac development.
-
- CodeWarrior (http://www.metrowerks.com/) : In early 1994, Metrowerks
- CodeWarrior came out of nowhere and grabbed a large share of
- the market visibility because they had the fastest compiler and
- they generated PowerPC code as well as 68K code from identical
- (though seperate) environments. Today, CodeWarrior has the smoothest
- development environment and most complete C++ implementation,
- supporting templates, exceptions, and RTTI on all supported platforms.
- CW/7 includes C, C++, and Object Pascal support, and can generate
- x86 and CFM-68k binaries, all from a single environment. A universal
- single-machine debugger is included for all Mac runtimes and
- a two-machine debugger is included for use with x86. CW is very
- popular because of it's low price, ultra-fast compile time, the
- honesty and integrity consistently displayed by Metrowerks employees
- (from the president of the company all the way down to the technical
- support people), and support that no other company on the planet
- has been able to match. comp.sys.mac.programmer.codewarrior
- for more information and CodeWarrior- related praise. Contact
- Metrowerks (mailto:sales@metrowerks.com) for more info.
-
- MPW: The grandaddy of all Mac development environments, descended
- from the original Mac & Lisa development environment hosted on
- the Lisa. MPW is an extremely flexible, powerful, vaguely Unix-like
- command line environment with makefile, multiple windows and
- unlimited split-pane support. Many, if not most, Mac development
- tools are MPW-based. The PowerPC compilers currently optimize
- better than either Symantec C++ or Metrowerks. MPW has in the
- past been extremely slow, but shows some signs of redemption.
- MPW Pro comes with C, C++, Pascal, assemblers for both 68k and
- PowerPC, various other useful tools, and the C++-based framework
- MacApp for a reasonable price. If you like the development tools
- under Unix, you might find MPW pleasant. While the question
- of Apple's commitment to MPW has arisen, it is a fact that the
- System Software is still built in MPW, so it can't be abandoned
- until at least some point after the release of Copland. Contact
- APDA for more info (mailto:apda@applelink.apple.com).
-
- Symantec C++ (http://www.symantec.com/lit/dev/macdv/macdv.html):
- This is the eighth-generation descendant of the Pascal and C
- development environments favored by Mac developers for over five
- years. Symantec C++ 8.0 is a complete, very scriptable, modular
- development environment including C, C++, Rez, and soon, a PowerPC
- assembler. The C++ implementation supports templates. A development
- version of a PowerPC C++ compiler supporting exceptions and RTTI
- is available at Symantec's devtools site. SC++ 8.0 doesn't at
- this time support 68k Mac development. For that purpose, you're
- required to use the old, decrepit TPM development environment,
- which is included. Symantec has recently fallen out of favor
- with Mac developers due to Microsoftian support policies, premature
- releases, general apathy in the past, and tendency to favor marketspeak
- over technical accuracy. Contact Symantec for more info.
- (mailto:sales@devtools.symantec.com)
-
- Of these three, CodeWarrior is the smoothest overall environment,
- with the most attention to detail, MPW is the hardest to use,
- (though the compilers provided with it generate the best PPC
- code and it's the most flexible), and Symantec C++ tends to be
- the most helpful in terms of project browsing features.
-
- Motorola (http://www.mot.com/SPS/PowerPC/) has a set of PowerMac
- C/C++ Fortran compilers, running under MPW only, which they
- claim generate code which is 20% faster than their next fastest
- competitor.
-
- If you're generating code for 68k Macs, your compiler's codegen
- won't be wonderful. There are no optimizing compilers for 68k
- Macintosh. Think C is slightly behind Metrowerks C in 68k code
- quality.
-
- There are also at least two Fortran compilers, at least three
- SmallTalk implementations (ObjectWorks, SmallTalk/V and SmallTalkAgents)
- and others. There are ways of stripping SmallTalk apps so they're
- smaller and faster as standalone apps than in the environment.
-
- Language Systems (http://www.cais.com/langsys/) has Object Pascal
- and Fortran for PowerMac. Absoft has Fortran and C++ for PowerMac.
- These all require MPW.
-
- There's also a world-class LISP/CLOS implementation from Apple
- called Macintosh Common Lisp. Recently, Apple announced that DigiTool
- (http://www.digitool.com/) has licensed MCL with the intent
- (among other things) to provide a PowerMac version and other
- updates.
-
- Zedcor has FutureBasic, which seems to be a very popular...
- It also seems to be the only well-supported compiler-based implementation
- of BASIC on Macintosh.
-
- CSI has MacForth, of which I only know the name and someone who
- says it's pretty good.
-
- There is another good Common Lisp implementation: Procyon Common
- Lisp. I don't know if it is actively supported, but Procyon
- CL is also available for DOS, OS/2 and Windows (as Allegro CL/PC)
- and actively developed.
-
- A new possible up-and-coming languge environment is Apple's
- Dylan.
-
- 1.3) Q: Okay, which is the most used Mac programming languge?
-
- A: The existing Macintosh code base is mostly C, with C++ second,
- and Pascal finding it's niche in third. Few people are writing
- mainstream software in Pascal anymore, probably because (a) it's
- rather hard to move to non-Mac platforms (b) Pascal is only rarely
- being taught past the first year in Computer Science. It's also
- been hard in the past to justify something like Borland's Delphi
- copyright infringement generator for Windoze.
-
- 1.4) Q: Where do I find a free/share/copyleftware C compiler
- for the Mac? Is there a GCC for the mac? What about the FSF
- boycott of Apple products?
-
- A: There is no really good solution for a "for-free" C development
- system for the Mac. GCC has been ported several times over,
- but requires the MPW shell and MPW assembler to run. There is
- a standalone port of GCC 1.37
- (ftp://nic.switch.ch/software/mac/src/think_c) by the same gentleman
- who brings you Patmos.
-
- A not-entirely-stable port of GCC 2.3.3
- (ftp://atg.apple.com/pub/MPW_gcc/GCC-2.3.3r12.sea.bin) to MPW
- is available for ftp at atg.apple.com. A much more solid port of
- GCC 1.37 is available for MPW as well.
-
- Stan Shebs (mailto:shebs@cygnus.com), the driving force behind
- all of the GCC -> MPW ports, was working on a new port of GCC
- 2.5.8, but seems to have given up.
-
- None of these ports is useful for doing real work.
-
- For those whose main interest is in developing only text-based
- C/C++ programs, using GCC under MacMiNT
- (ftp://nic.switch.ch/software/mac/src/macmint) might be appropriate.
- MacMiNT is a UNIX like operating system ported from the Atari
- ST which supports many freely available UNIX utilities like GCC,
- GDB, make, tcsh, byacc, perl, and more.
-
- The FSF/LPF boycott of Apple products is over as of January 1995,
- which means they will now incorporate changes made for Macintosh
- into the GNU (http://web.kaleida.com/u/hopkins/text/festo.html)
- main code base, if such changes are easily incorporated, and
- they won't be any more antagonistic to Mac programmers than they
- would be to any other non- Unix
- (http://web.kaleida.com/u/hopkins/unix-haters.html) programmers.
-
- 1.5) Q: Are there any other free Mac development platforms?
-
- A: The best source for information on free compilers/interpreters
- is the Free Development Tools on the Mac FAQ
- (http://www.europa.com/~sf/fdsm.html) maintained by Brian Conners.
-
- 1.7) Q: What good programmer’s text editors exist on the Mac?
-
- A: Several. You'll have to make up your mind as to which you
- prefer, as they differ widely in versatility, power, ease-of-use,
- and price.
-
- Alpha (http://www.cs.umd.edu/~keleher/alpha.html): This is the
- most powerful text editor, based on Dr. Ousterhout's Tcl scripting
- language with several extensions for text editing. Because Alpha's
- menus and all of the basic editing functions are controlled by
- Tcl procs, you can customize Alpha to do just about anything.
- Alpha supports editing modes for C, C++, Fortran, Pascal, HTML,
- PostScript, SQL, MPW Shell, Unix C shell, Perl, Tcl, (La)TeX
- and plain text. Keyword coloring is optional but the colors
- are fixed and rather dull. A generous library of Tcl routines
- is included, as is complete documentation. Alpha allows user
- scripts to build and send arbitrary AppleEvents. Frequent updates
- and support direct from the author. Limited split pane support.
- Alpha is $30 shareware.
-
- BBEdit (mailto:bbsw@netcom.com): This text editor has the slickest
- interface (easiest to use) and comes in two flavors, BBEdit Lite
- and the full commercial BBEdit. BBEdit, while only partially
- PowerMac native, is fast. BBEdit Lite is free and contains a
- large subset of the full BBEdit's features. BBEdit is fully
- scriptable and supports "soft" text wrapping, which allows one
- to have text wrapped automatically with hard returns while typing.
- External code module extensions are supported through a powerful
- parameter block interface. BBEdit contains fast navigation facilities
- for Pascal, C, C++, Rez, 68K Assembler, FORTRAN, HTML, CodeWarrior
- projects, SPM projects, and online volumes but does not currently
- support syntax coloring. BBEdit supports limited split panes.
- $119 - $79 ($39 for students).
-
- 1.8): Q: What kind of cross-platform solutions exist?
-
- Microsoft Visual C++ for Macintosh: a Windows NT or Windows 4.0
- hosted IDE which allows you to generate Mac applications from
- an Intel box. Microsoft Word was ported to Macintosh using VC++
- for version 6.0. Microsoft employees have claimed publicly that
- VC++ 4.0 will generate better code than all current Mac compilers.
-
- Altura (http://www.altura.com)'s Mac2Win: Altura's cross-platform
- solution, on the other hand, allows you to write a Macintosh
- application and then put an API translation layer on the Windows
- side. Very expensive, but a much improved end-result and happier
- users. 4D was ported to Windows using Mac2Win.
-
- Galaxy, Zapp, et cetra: [...working on this section, text contributions
- welcome!...]
-
- Doing the right thing on all platforms (providing the user interface
- expected by the user, including the use of features specific
- to each platform), requires you to use solutions built specifically
- for those platforms. One solution is to isolate platform-neutral
- code and use frameworks native to each platform. An example
- of a product built this way is Netscape Navigator. This assumes
- that you value your user's satisfaction above all else, which
- is the essence of programming Macintosh.
-
- 1.9): Q: Is there an Emacs port? Vi? EDT?
-
- A: Emacs: Yes. Marc Paquet has an excellent, mature, stable,
- and fat Emacs port. All the Unix geeks on Macintosh who I know
- use it. If you're looking for a more Maclike Emacs, try Alpha's
- Emacs bindings. (see 1.7). But Alpha doesn't have M-x doctor.
-
- Vi: There's a port called Stevie and a port called vim. If you
- know where to find these, tell me (mailto:ckt@best.com)! Again,
- Alpha has vi key bindings. But you don't get vi's wonderful
- lack of multiple on-screen buffers with Alpha.
-
- EDT: ? Does anyone care?
-
- 1.10) Q: What is a good low-level debugger for the Mac?
-
- A: MacsBug is freely available for ftp from ; log in as user
- anonymous and give your FULL e-mail address as password. MacsBug
- is your basic monitor-type debugger that takes a few hundred
- Ks of memory, and lets you break, step, disassemble, look at
- the stack etc of most anything running on your Mac. Since it's
- free (it's also on the developer CDs) and provides most of the
- functionality you need, this is a popular choice. As of 6.5d10,
- Macsbug supports PowerPC debugging.
-
- Jasik Designs (http://www.jasik.com/) has a debugger called The
- Debugger which can do both low- and high-level debugging, with
- or without source and for all types of code, application, code
- resources, everything. This is the debugger of choice for many
- large developers because of its high power and many features
- not found anywhere else. However; newcomers beware! This is
- the Lamborghini of debuggers; if you know how to drive it, it
- is the fastest way from A to B; if you don't, you'll just end
- up in the ditch. The Debugger is PowerMac native and supports
- PowerPC disassembly. It includes an excellent code coverage
- tool and MacNosy, a general disassembler. Support is direct
- from the author and generally great.
-
- 1.11) Q: Are there any visual developments environments for the
- Mac (comparable to Visual C++)?
-
- A: There is no Visual C++ as such. However, there is a C++ parser/editor
- called ObjectMaster which provides good browsing and editing
- capabilities if you already have a C++ compiler. A demo is available
- on the CodeWarrior CD. Symantec C++ comes with a browser built-in,
- and you can edit dialogs/windows using plain old ResEdit, even
- for your custom view types.
-
- Symantec C++ >= 7.0 also bundles a view editor/code generator
- called Visual Architect; it is fairly complete and has a good
- level of integration into the Think Project Manager.
-
- AppMaker is a GUI builder/code generator. Granted, it's not
- as nice as VC++, but it's quite a product in any case.
-
- MarksMan version 3.0 has totally revised TCL templates, and now
- generates well-thought-out TCL code. It can also generate ANSI
- C code etc.
-
- Also, Neuron Data has their UI tool called Open Interface, which
- is better than VC++ and creates code portable across 35 platforms.
- Unfortunately it's $2500 per developer per platform. There's
- also two other cross-platform products called XVT and Galaxy,
- the former has gotten flak on UseNet while the latter reportedly
- is the premier cross-platform application builder framework;
- with everything from styled text to network support.
-
- There is a fully visual, dynamic, object oriented data-flow-driven
- programming language for the Mac called Prograph CPX. It features
- a full-featured class library, a powerful, user-extensible GUI
- Builder, full access to the entire Mac toolbox, a database engine,
- high-level interfaces to SQL, Oracle, etc. But the coolest thing
- about Prograph is its interpretative debugger, fully integrated
- with the visual code editor, which lets you write your code _while
- it's running_. Execution automatically rolls back to where changes
- you make have relevance. A PowerMac-native compiler and a Windoze
- version are expected in '95. A complete demo version is available.
- Contact Prograph (mailto:sales@prograph.com) for more information.
- Cost is $695 ($395 for students).
-
- SmalltalkAgents comes with a GUI builder, which lets you draw
- your interface, and then outputs the code for you.
-
- If you'd rather do Common Lisp, Macintosh Common Lisp offers
- a Common Lisp Object System with support for most Mac interface
- items; you can edit code while it is running and build stand-alone
- applications.
-
- However, all of these tools generate rather larger binaries with
- larger system demands than a program written in C. On the other
- hand, C programs require more memory and disk space than programs
- written in assembly. It's a trade-off, and I believe this type
- of tool is the wave of the near future.
-
- 1.12) Q: What application frameworks exist for the Mac?
-
- A: In no particular order:
-
- MacApp (http://www.info.apple.com/dev/devinfo/macapp/macapp.html),
- Apple's framework, comes in two popular flavors, 2.x and 3.x.
- MacApp 2.x is grounded in Object Pascal, and is not being actively
- supported by Apple. 3.x is written in C++, retaining some Object
- Pascalisms which are somewhat weird from a C++ point-of-view.
- MacApp is very mature, with much support and many dependent
- applications outside of Apple, and is a good choice if you're
- not concerned about memory footprint. MacApp suffers in that
- it hasn't kept up with modern features such as threads, AOCE
- and the drag manager, resulting from a period of neglect, but
- has since been fully restaffed, and is well on the way to modern
- MacOS. MacApp is ideal for the developer looking for a very-low-risk,
- well-supported solution. A number of visual interface editors
- are available for MacApp. MacApp runs on all Mac C++ compilers,
- and CodeWarrior, as of CW/6, includes both MacApp 2 and 3. comp.sys.mac.oop.macapp3
- is a newsgroup dedicated to MacApp.
-
- The Think Class Library, originally written for Think C with
- Objects by the same gentleman who is now the PowerPlant lead
- architect, is a healthy, mature framework, with much third-party
- documentation and an active user community. TCL is included
- with Symantec C++, which also integrates Visual Architect, a
- customizable visual interface builder, into it's IDE. Other
- visual tools are available with TCL support. TCL, as of 2.0,
- is written in true C++. comp.sys.mac.oop.tclis a newsgroup dedicated
- to TCL discussion and support.
-
- PowerPlant (http://www.metrowerks.com/products/newcw7.shtml#powerplant):
- Distributed with Metrowerks' CodeWarrior development environment,
- PowerPlant is second-newest C++ framework, and takes advantage
- of the clean slate this affords it. PowerPlant is highly modular,
- being based on a number of mix-in classes, and contains support
- for many modern MacOS features, including the Open Scripting
- Architecture, PowerTalk/AOCE, Drag Manager, threads, and others.
- Because of the modern design It's still a work-in-progress,
- with many rough edges. PowerPlant is ideal for the developer
- who desires a clean, modern architecture and is willing to put
- up with the aforementioned holes. CodeWarrior ships with PowerPlant
- Constructor, a view editor.
-
- ODF: The OpenDoc Parts Framework, another Apple framework, is
- intended solely for (surprise!) OpenDoc part development. ODF
- recycles chunks of the failed cross-platform Bedrock project.
- Although the other frameworks will probably support OpenDoc
- to varying degrees at some point, only ODF is committed to supporting
- all of OpenDoc, with cross-platform support encompassing MacOS,
- Windows, and probably other platforms in the future. Both Metrowerks
- and Symantec have licensed ODF and will include it in their products
- at some point in the future. Currently, no tools exist for human
- interface construction with ODF.
-
- Sprocket (http://www.mactech.com/sprocket.html): Sprocket is
- a very simple class library, using MacApp coding style organization,
- but supporting relatively bleeding-edge features such as AOCE
- mailer support, threaded AppleEvent futures, threads in general,
- Drag Manager support, and multiple floating palette support.
- Sprocket was written by Dave Falkenburg of Apple for an article
- in MacTech, and serves as a testbed for new technologies presented
- therein. Ideal for those looking for a small, easy to understand
- class framework with support for some modern MacOS features.
-
- TransSkel: A solid C framework, TransSkel is very easy to program,
- is well-documented, and lends itself to small-footprint/small-resource-
- requirement applications. An unsupported Pascal version is available.
-
- 1.13) Q: How should I debug and test my software?
-
- A: Get ahold of, and install, the extensions DoubleTrouble, DisposeResource
- and EvenBetterBusError. They will catch 80% of any memory related
- bugs you may have, including many bugs that follow NULL handles
- or pointers. (Jasik's Debugger (see above) obviates the need
- for these, as does a control panel called QC (mailto:OnyxTech@aol.com).)
-
- A low-level debugger is required, and while you install it, install
- the "leaks" dcmd which will help you catch memory leaks in your
- application. Check out Apple's developer site for most of these
- tools. (ftp://www.info.apple.com/).
-
- 1.14) Q: Are there any good Mac programming magazines?
-
- A: One Mac programming magazine I know of is MacTech Magazine
- (mailto:custservice@xplain.com) (formerly MacTutor). It covers
- a variety of Mac programming topics on various levels. Operating
- independently from Apple, it has a lot of stuff for the beginning
- Mac programmer, as well as occasional nuggets for the more experienced
- of us.
-
- Another excellent magazine is _develop_
- (mailto:dev.subs@applelink.apple.com) which is put out by Apple
- four times a year; it comes with a CD containing all past issues
- of _develop_ in electronic form, all source code included with
- those issues, and a rotating set of electronic Inside Macintosh
- books. $30/year in the US.
-
- MacTech tends to lean toward a general Mac programming folklore
- feel; _develop_ tends to lean towards Apple employees writing
- articles which show how to implement the latest cool technology,
- with occasional new System Software technical preview. The Developer
- CD includes _develop_ in electronic form, and _develop_ is also
- available free from Apple's various online sites.
-
- 1.15) Q: What about protected memory? I'm sick and tired of re-booting
- when my application crashes.
-
- A: Write better software!
-
- Or install The Debugger from Jasik Designs, which can provide
- your application with write-protection of critical parts of memory,
- if you have a 68030-equipped Mac.
-
- Making the Mac OS memory-protected is tricky, because applications
- expect to be able to write to low memory, the system heap, temporary
- memory, window lists, and even each other's heaps in some interapplication
- communication solutions that date back to before AppleEvents
- and the PPC Toolbox.
-
- But fear not, Mac fans! Jonathan Kimmitt has written Patmos
- (ftp://nic.switch.ch/software/mac/src/patmos), the "Protected
- address translation mode operating system". It is an application
- that brings the advantages of protected mode programs to your
- Quadra class Macintosh by the simple expedient of taking over
- the memory management unit of the 68040 in a very simple kernel
- ( less than 100K in size), we immediately gain compatibility
- with the BSD unix program environment.
-
- The downside is that not all macs use the memory management unit
- in the same way, or even have the same kind of MMU, so Patmos
- may not run on your particular mac model. However, since the
- kernel source code is very small, the task of adapting it to
- a new environment is very simple, and once achieved, all application
- programs running in user mode are enabled to run without even
- recompiling.
-
- 1.16) Q: What are some good books on the subject of learning
- the Mac Toolbox?
-
- A: Any of Dan Parks Sydow's numerous books on the subject. Recommended
- also is Dave Mark's _Ultimate Mac Programming_ (a Macworld book,
- for some odd reason). Stay away from Dave Mark's _Learn C on
- the Mac_ and _Learn C++ on the Mac_, as these don't teach the
- Mac toolbox, and better books exist for learning straight C or
- C++.
-
- See also Nick DeMello's books review, posted in c.s.m.p.info
- from time to time.
-
- 1.17) Q: Where can I find some source code?
-
- A: Celestin Company, Inc. sells the Apprentice CD-ROM
- (ftp://ftp.teleport.com/vendors/cci/apprentice/apprentice.hqx).
- Apprentice contains over 600 megabytes of programmer utilities
- and up-to-date source code in CodeWarrior, Symantec, and MPW
- projects for C, C++, Pascal, and assembler.
-
- Also, the alt.sources.mac archive
- (ftp://ftp-2.amug.org/pub/demos/alt.sources.mac/) contains a
- lot of miscellaneous source code and snippets not found elsewhere.
-
- SWITCHinfo (ftp://nic.switch.ch/pub/mac/src) is another good
- source for unique source code.
-
- Your local info-mac mirror is a good source for source, info-mac/dev/src.
-
- 1.18) Q: I keep getting dumped into Macsbug with a "PowerPC Memory
- Access Exception," and I can't get rid of it by typing G or ES.
-
- A: This means one of two things:
-
- 1. Something invalid was passed to the Memory Manager, and will
- be ignored. You can just go ahead and type GP (might be necessary
- to do this several times.)
-
- 2. A program is really trying to access memory that it can't.
- Type GP;ES and press return.
-
- 1.19) Q: ResEdit is useless. Where can I find a professional
- resource editor?
-
- Resorcerer (mailto:resorcerer@aol.com), the only professional
- Resource Editor for Macintosh, happens to be an excellent replacement
- for ResEdit. Aside from a few interface quirks, the template
- facilities put ResEdit to shame, as does the dialog editor, and
- just about everything else. $256 commercial. Student discounts
- are available.
-
- There are no PowerPC-native resource editors at the moment.
-
- 1.20) Q: What source code/revision control tools are available
- for Macintosh.
-
- A: Text-based?
-
- RCS and SCCS ports: available. Check info-mac/dev/src for these.
-
- MPW Projector: Projector is a simple text-based MPW tool included
- with MPW. Supports experimental branches. Will be phased out
- at some point.
-
- SourceServer: a standalone version of Projector using an AppleEvent-based
- interface to communicate with clients.
-
- SourceSafe: another text-based source code control system. Microsoft
- owns this now, but Metrowerks licensed the right to develop and
- sell the Mac version, and announced plans to give it a true graphical
- interface. Expect to hear more around late '95/spring '96.
-
- or Graphical?
-
- Voodoo (mailto:chrei@unisoft.co.at): Versions Of Outdated Documents
- Organized Orthogonally is a system which supports the storage
- of both multiple revisions of a single component and different
- variants of that component. Additionally, Voodoo only stores
- data which is different in each variant, thereby potentially
- saving much disk space. Users have given Voodoo (and it's shareware
- sibling, Voodoo Lite) glowing reviews in c.s.m.p.tools.
-
- Source Manager is an easy-to-use graphical front-end to Projector,
- SourceServer, and SourceSafe. A demo of the most recent version
- is available at info-mac/dev/. Source Manager is shareware.
-
- *2* Memory
-
- 2.1) Q: What is a handle?
-
- A: A handle is a pointer to a pointer to something. However,
- it is more than that; creating a handle by taking the address
- of one of your own pointers does NOT create a Handle; the Memory
- Manager will only deal properly with Handles that are created
- using NewHandle or something that calls it (such as NewRgn or
- GetResource).
-
- 2.2) Q: When do I have to lock a Handle?
-
- A: The contents of a Handle may move, and when it does, the pointer
- your handle is pointing to is changed to point to the new address
- so your handle is always valid. The toolbox may call the memory
- manager to allocate more memory pretty much anytime you call
- it (the toolbox) and when memory is allocated, your handle may
- move in memory. Don't dereference a handle into a pointer (or
- take the address of a field in a record a handle is double-pointing
- to) and then call the toolbox and expect the pointer to still
- be valid. The only way to ensure that the pointer will still
- be valid is to call HLock on the handle to lock it.
-
- Use HGetState and HSetState to save & restore the "locked" state
- of a handle when you lock it.
-
- 2.3) Q: How do I dispose of Handles?
-
- A: DisposeHandle (formerly called DisposHandle) once and ONLY
- once will do the trick. Trying to dispose of an already disposed
- Handle is an error. DoubleTrouble (see above) will catch such
- bugs when they do occur.
-
- 2.4) Q: What about resources?
-
- A: Calling GetResource returns NULL if the resource is not found
- or there is not enough memory, else it returns a handle to the
- resource. This handle may be moved or locked like any other
- handle, but DO NOT call DisposeHandle to get rid of a resource
- handle - call ReleaseResource. DisposeResource (see above) will
- catch this kind of bug.
-
- Remember that AddResource makes a resource handle out of an ordinary
- handle, and RemoveResource or DetachResource makes an ordinary
- handle out of a resource handle. You cannot call AddResource
- with a resource handle; you have to DetachResource it first.
-
- Remember also that once a resource has been detached with DetachResource,
- it becomes a handle like any other handle, and must be disposed
- via DisposeHandle.
-
- Resource handles are automagically disposed when the resource
- file they belong to is closed.
-
- *3* User / Machine interaction
-
- 3.1) Q: How do I read the modifier keys of the keyboard?
-
- A: Just call EventAvail and check the event.modifiers field.
- Only works when you are in the foreground. You can also use GetKeys(),
- or (as a last resort) check the lo-mem global KeyMap directly.
-
- 3.2) Q: How do I move the mouse cursor to a specific position?
-
- A: Wait! Don't do it! There has to be a better way!
-
- If you feel you HAVE to do it (for a game or VERY special simulation
- situation) you can use the Cursor Device Manager documented in
- the tech notes . If that manager is not installed, as it's
- not on older Macs, you can use the following code:
-
- You need to have some low-memory globals defined. they may be
- defined in SysEqu.h.
-
-
- #define MTemp 0x828
- #define RawMouse 0x82c
- #define CrsrNewCouple 0x8ce
-
- Note that CrsrNewCouple is actually a combination of two globals,
- just to make our life slightly easier.
-
- The code I use to move the mouse is:
-
- void MoveMouseTo ( Point where )
- {
-
- HideCursor ( ) ;
- * ( Point * ) RawMouse = where ;
- * ( Point * ) MTemp = where ;
- * ( short * ) CrsrNewCouple = -1 ;
- ShowCursor ( ) ;
- }
-
- You need to hit a couple more global variables if you want this
- to work properly in a multiple-monitor system, but i forget what
- they are offhand. poke through SysEqu.h, and you should be able
- to figure it out without a problem.
-
- On the PowerPC, these lo-mem globals may not be available for
- native applications; however, all Power Macintoshes implement
- the Cursor Device Manager. 68k Macs implement it beginning with
- the Centrises.
-
- There is also a file on nada.kth.se:pub/hacks/mac-faq/MoveMouse.c
- which shows how to use the Cursor Device Manager, written by
- an excellent Apple engineer. Grab!
-
- Careful, version 1.0 of the Universal Header "CursorDevices.h"
- file was completely incorrect. Use 2.0a3 or later.
-
- 3.3) Q: My menus don't show up in the menu bar.
-
- A: If your menus are hiearchical, you'll have to install them
- manually; GetNewMBar won't do it for you. See also 3.5.
-
- 3.4) Q: When the user selects my menus, I get strange results
- back; they seem to have different menu IDs than my menus?
-
- A: The Menu ID as used by the menu manager is NOT the same thing
- as the MENU resource ID (used in the MBAR resource and with GetMenu())
- When you create a MENU, ResEdit sets the menu ID to the MENU
- resource ID, but if you re-number the resource, you will have
- to open the menu in ResEdit and change the menu ID using the
- "Edit MENU ID" menu item.
-
- 3.5) Q: I use GetMenu() to find a menu in the menu bar, and then
- change it, but it seems I have a memory leak OR my changes don't
- "punch through"
-
- A: GetMenu() is only intended if you don't already have the menu
- "in memory." The call you should use almost all the time is GetMHandle()
- which gets the handle to a menu in the current menu bar by its
- menu ID (not resource id).
-
- 3.6) Q: What about pre-emptive multitasking?
-
- A: To the user, the Mac multitasking method, which builds upon
- each application calling WaitNextEvent, GetNextEvent or EventAvail
- every so often and the Process Manager/MultiFinder switching
- applications only at such calls, is at least as good as preemptive
- multitasking, because the present system priotitizes user interface
- responsiveness over everything else. The only shortfall about
- this is formatting floppies which on most 68k Macs locks up the
- CPU. This is because the 68k Mac floppy controller is really
- stupid, and would happen even if the 68k Mac multitasked preemptively.
-
- There IS "real" pre-emptive multitasking available for use in
- Mac applications; the expensive way is buying A/UX 3.0 which
- can have Mac applications written as UNIX processes; the cheap
- way is installing the Thread Manager which will allow you to
- create pre-emptive threads. However, the restrictions on those
- threads are the same as those on Time Manager tasks: don't call
- any function in an unloaded segment, and don't call QuickDraw
- or any toolbox call which may move memory (which are most ToolBox
- calls; paradoxally, BlockMove is safe :-) as are, surprisingly,
- FSRead and FSWrite). The latest word from Apple is that this
- preemptive support is going away, to be replaced by preemptive,
- memory-protected kernel tasks in Copland. You should thread
- your applications now to prepare for the move to Copland.
-
- There are several problems with making the Mac OS preemptive
- with memory protection; including apps that draw outside their
- windows or directly to screen, user dragging and other issues.
- The system is being entirely reimplemented for 8.0 (Copland)
- to help solve these problems in a manner compatible with today's
- cooperative apps. System 9.0 will offer full preemptive multitasking.
-
- *4* Files
-
- 4.1) Q: How do I tell fopen() to open a file the user has selected
- using StandardGetFile?
-
- A: The "standard" ANSI C file functions are less than well suited
- for the Macintosh way of doing things. However, if you are doing
- a port for your own enjoyment and benefit (or maybe for in-house
- work) you can use the following function: (see below about converting
- a wdRefNum into a vRefNum/parID pair)
-
- FILE * fopen_mac ( short vRefNum , long parID , char * fileName
- , char * mode )
- {
-
- short oldVol ;
- short aVol ;
- long aDir , aProc ;
- FILE * ret = NULL ;
-
- /* save old default directory/volume */
- if ( GetVol ( NULL , & oldVol ) ) {
- return NULL ;
- }
-
- /* from working directory->directory/volume */
- if ( GetWDInfo ( oldVol , & aVol , & aDir , & aProc ) ) {
- return NULL ;
- }
-
- /* change default directory */
- if ( HSetVol ( NULL , vRefNum , parID ) ) {
- return NULL ;
- }
-
- /*call ANSI fopen*/
- ret = fopen ( fileName , mode ) ;
- if ( HSetVol ( NULL, aVol , aDir ) ) {
- /* an error we can't currently handle */
- }
-
- /* restore old volume/directory */
- if ( SetVol ( NULL, oldVol ) ) {
- /* an error we can't currently handle */
- }
- return ret ;
- }
-
- All of the above is necessary for one reason or another - if
- you are interested, by all means look HSetVol up in MPTA or New
- Inside Mac: Files.
-
- In older versions of MPW, this wouldn't work since the MPW libraries
- used to do a GetVol and explicitly use that value by itself.
-
- 4.2) Q: When can I use the HOpen, HCreate etc file calls? Are
- they only System 7 calls?
-
- A: All the HXxx calls that take a vRefNum and parID as well as
- the file name are implemented in glue that works on any system
- that has HFS (meaning 3.2 and up with the HD20 INIT, and all
- systems from System 6 and up)
-
- The glue is available in MPW 3.2 and up, and Think C 5.0 and
- up. This goes for all HXxx calls except HOpenDF; therefore,
- if you are interested in System 6 compatibility, use HOpen instead
- and make sure you don't allow file names beginning with a period.
-
- 4.3) Q: Why do you say wdRefNum sometimes and vRefNum sometimes?
- Why do you say parID sometimes and dirID sometimes?
-
- A: When the Mac first made an appearance in 1984, it identified
- files by using a vRefNum (volume reference number meaning a floppy
- disk or later hard disk) and a name. Once HFS saw the light
- of day, folders within folders became a reality, and you needed
- a dirID as well to point out what folder you really meant on
- the volume. However, older programs that weren't being rewritten
- still knew nothing about directory IDs, so Apple had SFGetFile
- make up "fake" vRefNums that didn't just specify a volume, but
- also a parent folder. These are called wdRefNums (for working
- directory) and were a necessary evil invented in 1985. You should
- not create (or, indeed, use) wdRefNums yourself.
-
- There is a system-wide table that maps wdRefNums onto vRefNum/parID
- pairs. There is a limit to the size of this table. A dirID
- and a parID is almost the same thing; you say "parID" when you
- mean the folder something is in, while you say a "dirID" when
- you mean the folder itself. If you for instance have a folder
- called "Foo" with a folder called "Bar" in it, the parID for
- "Bar" would be the dirID for "Foo."
-
- 4.4) Q: How do I convert a wdRefNum as returned by SFGetFile
- into a vRefNum/parID pair to use with the HXxx calls?
-
- A: Use GetWDInfo, which is declared as:
-
- Pascal OSErr GetWDInfo ( short wdRefNum, short * vRefNum,
- long * parID, OSType * procID
- ) ;
-
- The procID parameter must be non-NULL and point to an OSType
- variable, but the value of that variable can and should be ignored.
-
- It is recommended that, as soon as you get your hands on a wdRefNum,
- for instance from SFGetFile, you directly convert it into a vRefNum/parID
- pair and always use the latter to reference the folder.
-
- For maximum compatibility with future systems, you should actually
- be using the newer StandardGetFile and StandardPutFile functions
- that were introduced with System 7.
-
- 4.5) Q: How do I select a folder using SFGetFile?
-
- A: This requires a custom dialog with a filter proc. It is too
- complicated to show here, but not totally impossible to comprehend.
- There is sample code on ftp.apple.com, in the directory dts/snippets,
- on how to do this.
-
- 4.6) Q: How do I get the full path of a file referenced by a
- vRefNum, parID and name?
-
- A: You don't.
-
- OK, I cheated you. There is exactly ONE valid reason to get
- the full path of a file (or folder, for that matter) and that
- is to display its location to the user in, say, a settings dialog.
- To actually save the location of the file you should do this:
- (assuming the file is in an FSSpec called theFile - you can use
- FSSpecs in your program even if you don't run under System 7;
- just make your own MyFSMakeFSSpec that fills in the FSSpec manually
- if it's not implemented)
-
-
- if ( ! aliasManagerAvailable ) { /* System 6 ? */
- GetVolumeName ( theFile -> vRefNum , vName ) ;
- GetVolumeModDate ( vRefNum , & date ) ;
- Save ( vName , date , parID , fileName ) ;
- } else {
- NewAlias ( NULL , theFile , & theAlias ) ;
- Save ( theAlias ) ;
- DisposeHandle ( ( Handle ) theAlias ) ;
- }
-
- If you are really concerned about these issues (of course you
- are!) you should save BOTH of these methods when available, and
- load back whatever is there that you can handle; since users
- may be using your application in a mixed System 6/System 7 environment.
-
- To get back to the file is left as an exercise for the reader.
-
- To open a file using fopen() or the Pascal equivalent, see above
- about using and not using HSetVol.
-
- 4.7) Q: What about actually getting the full path for a file?
- I promise I will only use it to show the location of a file to
- the user!
-
- A: The easiest way to do this is to grab Jim Luther's excellent
- and complete MoreFiles (1.3 or later), which does all this work
- for you (see 4.15).
-
- Enter PBGetCatInfo, the Vegimatic of the Mac file system. Any
- Mac hacker of knowledge has taken this system call to his heart.
- Note that this sample code isn't all there, but should point
- you in the right direction:
-
- Boolean IsFolder(FSSpec *fs) // this function is called later
- {
- CInfoPBRec rec;
-
- rec.hFileInfo.ioNamePtr = fs -> name;
- rec.hFileInfo.ioVRefNum = fs -> vRefNum;
- rec.hFileInfo.ioDirID = fs -> parID;
-
- if ( !fs -> name [ 0 ] )
- {
- rec . hFileInfo . ioFDirIndex = 0 ;
- }
- else
- {
- rec . hFileInfo . ioFDirIndex = -1 ;
- }
-
- rec . hFileInfo . ioFVersNum = 0 ;
- PBGetCatInfoSync (&rec);
-
- return(!rec.hFileInfo.ioFlAttrib & 0x10);
- }
-
- OSErr GetFolderParent(FSSpec *fss, FSSpec *parent)
- {
- CInfoPBRec rec;
- short err;
-
- *parent = *fss;
- rec.hFileInfo.ioNamePtr = parent -> name ;
- rec.hFileInfo.ioVRefNum = parent -> vRefNum ;
- rec.hFileInfo.ioDirID = parent -> parID ;
-
- if ( !parent -> name [ 0 ] )
- {
- rec . hFileInfo . ioFDirIndex = 0 ;
- }
- else
- {
- rec . hFileInfo . ioFDirIndex = -1 ;
- }
-
- rec . hFileInfo . ioFVersNum = 0 ;
- err = PBGetCatInfoSync ( & rec ) ;
-
- if ( ! ( rec . hFileInfo . ioFlAttrib & 0x10 ) ) { /* Not
- a folder */
- if ( ! err ) {
- err = dirNFErr ;
- }
- } else {
- parent -> parID = rec . dirInfo . ioDrParID ;
- BlockMove(rec.dirInfo.ioNamePtr, parent->name, rec.dirInfo.ioNamePtr[0]);
- }
- return err ;
- }
-
- OSErr GetFullPathHandle ( FSSpec * fss , Handle * h )
- {
- Handle tempH = NULL;
- FSSpec fs = * fss ;
- FSSpec sSpec;
-
- if(*h == NULL) // allocate a handle if needed
- {
- *h = NewHandle(0);
- }
-
- while ( fs . parID > 1 )
- {
- tempH = NULL ;
- PtrToHand ( & fs . name [ 1 ] , & tempH , fs . name [ 0
- ] ) ;
- PtrAndHand ( ( void * ) ":" , tempH , 1 ) ;
- HandAndHand ( * h , tempH ) ;
- SetHandleSize ( * h , 0L ) ;
- HandAndHand ( tempH , * h ) ;
- DisposeHandle ( tempH ) ;
-
- tempH = NULL ;
- GetFolderParent ( & fs , & sSpec ) ;
- fs = sSpec ;
- }
-
- // fs should now contain info about the volume itself
- PtrToHand ( & fs . name [ 1 ] , & tempH , fs . name [ 0 ] )
- ;
- PtrAndHand ( ( void * ) ":" , tempH , 1 ) ;
- HandAndHand ( * h , tempH ) ;
- SetHandleSize ( * h , 0L ) ;
- HandAndHand ( tempH , * h ) ;
- DisposeHandle ( tempH ) ;
- tempH = NULL ;
-
- if (!IsFolder ( fss ) )
- {
- SetHandleSize ( * h , GetHandleSize ( * h ) - 1 ) ;
- }
-
- DisposeHandle(tempH);
- return 0 ;
- }
-
- 4.8) Q: So how do I get the names of the files in a directory?
-
- A: You use PBGetCatInfo again, but this time you set ioFDirIndex
- to 1 or more (you need to know the dirID and vRefNum of the folder
- you're interested in) You then call PBGetCatInfoSync for values
- of ioFDirIndex from 1 and up, until you get an fnfErr. Any other
- err means you are not allowed to get info about THAT item, but
- you may be for the next. Then collect the names in the string
- you made ioNamePtr point to as you go along. Note that you need
- to fill in the ioDirID field for each iteration through the loop,
- and preferably clear the ioFVersNum as well.
-
- Note that the contents of a directory may very well change while
- you are iterating over it; this is most likely on a shared folder.
-
- 4.9) Q: How do I find the name of a folder for which I only know
- the dirID and vRefNum?
-
- A: You call (surprise!) PBGetCatInfo! Make ioNamePtr point to
- an empty string (but NOT NULL) of length 63 (like, an Str63)
- and ioFDirIndex negative (-1 is a given winner) - this makes
- PBGetCatInfo return information about the vRefNum/dirID folder
- instead of the file/folder specified by vRefNum, parID and name.
-
- 4.10) Q: How do I make the Finder see a new file that I created?
- Or if I changed the type of it; how do I display a new icon for
- it?
-
- A: In pre-7.5 Finders, you call (surprise!) PBGetCatInfo followed
- by PBSetCatInfo for the FOLDER the file is in. Inbetween, you
- should set ioDrMdDat to the current date&time. Code:
-
- OSErr TouchFolder ( short vRefNum , long parID )
- {
-
- CInfoPBRec rec ;
- Str63 name ;
- short err ;
-
- rec . hFileInfo . ioNamePtr = name ;
- name [ 0 ] = 0 ;
- rec . hFileInfo . ioVRefNum = vRefNum ;
- rec . hFileInfo . ioDirID = parID ;
- rec . hFileInfo . ioFDirIndex = -1 ;
- rec . hFileInfo . ioFVersNum = 0 ;
- err = PBGetCatInfoSync ( & rec ) ;
- if ( err ) {
- return err ;
- }
- GetDateTime ( & rec . dirInfo . ioDrMdDat ) ;
- rec . hFileInfo . ioVRefNum = vRefNum ;
- rec . hFileInfo . ioDirID = parID ;
- rec . hFileInfo . ioFDirIndex = -1 ;
- rec . hFileInfo . ioFVersNum = 0 ;
- rec . hFileInfo . ioNamePtr [ 0 ] = 0 ;
- err = PBSetCatInfoSync ( & rec ) ;
- return err ;
- }
-
- 4.11) Q: Aren't we done with PBGetCatInfo soon?
-
- A: Well, it turns out that you can also find out whether an FSSpec
- is a file or a folder by calling PBGetCatInfo and check bit 4
- (0x10) of ioFlAttr to see whether it is a folder. You may prefer
- to call ResolveAliasFile for this instead.
-
- You can also check the script of the file's title using PBGetCatInfo
- and check the ioFlFndrXInfo field if you want to work with other
- script systems than the Roman system.
-
- Another common use is to find out how many items are in a folder;
- the modification date of something or the correct capitalization
- of its name (since the Mac file system is case independent BUT
- preserves the case the user uses)
-
- 4.12) Q: How do I set what folder should initially be shown in
- the SFGetFile boxes?
-
- A: You stuff the dirID you want to show into the lo-mem global
- CurDirStore, and the NEGATIVE of the vRefNum you want into the
- lo-mem global SFSaveDisk.
-
- If you are using CustomGetFile and return sfSelectionChanged
- from an "init" message handler, you must remember to clear the
- script code, else the selection will not change.
-
- 4.13) Q: How do I find the folder my application started from?
- How do I find the application file that's running?
-
- A: Under System 7, you call GetProcessInformation using the ProcessSerialNumber
- kCurrentProcess with a pointer to an existing FSSpec in the parameter
- block. This will give you your file, and, by using the vRefNum
- and parID, the folder the application is in.
-
- OSErr CurrentProcessLocation(FSSpec *applicationSpec)
- {
- ProcessSerialNumber currentPSN;
- ProcessInfoRec info;
-
- currentPSN.highLongOfPSN = 0;
- currentPSN.lowLongOfPSN = kCurrentProcess;
- info.processInfoLength = sizeof(ProcessInfoRec);
- info.processName = NULL;
- info.processAppSpec = applicationSpec;
- return ( GetProcessInformation(¤tPSN, &info) );
- }
-
- If you want to create a folder or file in your application's
- directory, call FSMakeFSSpec(0, 0, "\pNameOfFolderOrFile" &theSpec).
-
- Don't write to your applications resource or data forks; the
- former breaks on CDs/write protected floppies/file servers/virus
- checkers, the latter fails on PowerPC as well as in the above
- cases.
-
- 4.14) Q: When can I use those nifty, easy to use FSSpec calls?
-
- A: In Systems >= 7, in System 6 with QuickTime installed (with
- limitations), in any system if you use the FSpCompat functions
- provided by MoreFiles [see below].
-
- 4.15) Q: This low-level file manager stuff is giving me a headache;
- why didn't Apple provide a complete high-level interface using
- FSSpecs?
-
- A: Good question. Apple, in the guise of Jim Luther of Mac Developer
- Technical Support, has written a library called MoreFiles
- (ftp://ftp.info.apple.com/Apple.Support.Area/Developer_Services/Sample_Code/MoreFiles_1.3.1),
- which not only provides a high-level interface to low-level file
- stuff, but provides FSSpec glue for Systems below 7. MoreFiles
- is available on the Developer CD's (see 1.7) and also at Appple's
- developer web site. MoreFiles is complete and well-written.
- Grab!
-
- *5* Imaging with QuickDraw
-
- 5.1) Q: Why is CopyBits so slow?
-
- A: It is not. It just requires some hand-holding to get good
- results. The main rules are: Make sure the source and destination
- pixMaps are of the same depth.
-
- Make sure the front color is black and the back color is white.
-
- Use srcCopy and don't use a masking region, unless it's rectangular.
-
- Copy to an unclipped window (the frontmost window). Make sure
- the ctSeed values of the source pixMap and dest pixMap match.
-
- Copying few and large pixMaps is faster than copying many and
- small ones. Icon-sized sprites count as small ones.
-
- Make sure your source bitmap or pixelMap has the same alignment,
- when adjusted for the source and destination rect expressed in
- global screen coordinates. The necessary alignment is 32 bits
- (4 bytes), although 128 bit (16 byte) alignment is probably even
- better on 68040 macs and won't hurt on other macs.
-
- Example of global alignment:
-
- Your window is positioned at (42,100) (H,V)
-
- Your destination rectangle is (10,20)-(74,52)
-
- The alignment coefficient of the rectangle in global coordinates
- is (42+10)*bitDepth where bitDepth is one of 1,2,4,8,16 or 32.
-
- Make sure your source pixmap rect has the same coeffecient modulo
- your alignment factor (in bits) For black&white macs, this is
- still true, although bitDepth is fix at 1. Offscreen pixMaps
- can calculate with a "global posistion" of 0,0 and get correct
- results.
-
- 5.2) Q: Why is CopyBits still too slow?
-
- A: Because there is always some overhead involved in calling
- QuickDraw; you have the trap dispatcher, clipping checks, and
- checking whether the CopyBits call is being recorded in a PICT
- handle (if you called OpenPicture)
-
- If you can't live with this, look at 4.8 below, but PLEASE try
- and make CopyBits work, and retain the CopyBits code in your
- application, so users with special monitors (accellerator cards,
- PowerBook color screens, Radius Pivot screens) can still play
- your game. (non-game applications don't need more speed than
- CopyBits can give at its max. Promise!)
-
- 5.3) Q: What is the fastest way to set one pixel?
-
- A: NOT SetCPixel()! Assuming you have the correct ForeColor()
- set, you can set the pen size to (1,0) and call Line (0,1)
-
- I have heard PaintRect is good for this but requires slightly
- more code. Using PaintRect eliminates a trap call.
-
- 5.4) Q: Why do pictures I record suddenly draw as empty space
- or not draw at all?
-
- A: When recording pictures, you have to set the clipping area
- to exactly the frame of the picture you are recording. This
- is because it is initally set at -32768,32727 in both directions,
- and offsetting the picture even one pixel when drawing it will
- result in the region wrapping around and becoming empty.
-
- When recording pictures, do this:
-
- PicHandle h = OpenPicture ( & theRect ) ;
- ClipRect ( & theRect ) ;
- /* draw the picture */
- ClosePicture ( ) ;
-
- 5.5) Q: Where can I find the format of picture files and resources?
-
- The format of a picture resource version 2 is defined in Inside
- Mac: Imaging with QuickDraw.
-
- The format of a picture file is the same as that of a picture
- resource with 512 added 0 bytes in front.
-
- 5.6) Q: GWorlds?
-
- A: What about them? They're great. Look them up in IM: Imaging
- With QuickDraw. Don't forget to SetGWorld back to what it was
- and unlock the pixmap before calling WaitNextEvent.
-
- 5.7) Q: How do I find the current depth of the screen?
-
- A: My question to you is: What screen? Many macs have more than
- one screen attached. You can use GetDeviceList and walk the
- devices to find the screen you're looking for (use TestDeviceAttribute
- to see whether it's a screen) or you can call GetMaxDevice()
- to find the deepest device your window intersects.
-
- Once you have the device handle, finding the depth is just a
- matter of looking at the gdPMap pixMapHandle, and dereference
- it to the pmSize field. Done.
-
- 5.8) Q: Why is it a bad idea to draw directly to screen?
-
- A: Because of several reasons:
-
- You will be incompatible with future display hardware.
-
- You will be incompatible with some present-day display hardware,
- such as Radius Pivots and PowerBook color screens.
-
- You have to think about a lot of things; testing it all on your
- own machine is not possible and the chances of crashing are great.
-
-
- You will be incompatible with future hardware where devices
- may live in some unaccessible I/O space.
-
- 5.9) Q: But I really need to do it. I can't make my animation
- into a QuickTime movie, and CopyBits is too slow, even when syncing
- to the screen retrace and with my source GWorld aligned properly.
-
- A: You have to prepare yourself, and ask these questions:
-
- Do I want to support all screens, or just 8-bit devices?
-
- Do I have a few weeks of free time to make it work?
-
- Do I want to get nasty mail when I break on some hardware and
-
- have to rev the application - even if I may not be able to
- get
- ahold of the hardware that makes it break?
-
- If all you're doing is rendering an image pixel-by-pixel or line-by-line,
- maybe you can draw directly into an offscreen pixMap/GWorld and
- then CopyBits the entire GWorld to screen. That will be more compatible,
- especially if you use the keepLocal flag when creating the GWorld.
-
- 5.10) Q: Okay, so how do I get the base address of the screen?
-
- A: "The" screen? Which screen? There may be several. The base
- address may be on an accellerated screen card. There may be more
- than one screen covering the same desktop area.
-
- Due to unfortunate circumstances, there is a bug in GetPixBaseAddr()
- that causes it to return incorrect results for early versions
- of System 7. Instead, get the baseAddr directly from the gdPMap
- handle of the GDHandle for the screen you draw to. This address
- may need switching to 32bit mode to be valid.
-
- 5.11) Q: Quit stalling and give me code!
-
- A: Okay, but I'll let you sweat over Inside Mac to figure out
- what it does. All of it is important; believe me! To make this
- code run faster, a lot of the things it does can be done once
- before starting to draw.
-
- Make sure that you have a window that covers the area where you
- are drawing, so other windows will not be overdrawn. Also make
- sure that you do not do direct-to-screen-drawing while you are
- in the background.
-
- /* This is presently untested code */
- /* Value is dependent on what depth the screen has */
- /* This code doesn't work on non-color-quickdraw Macs */
- /* "where" is in GLOBAL coordinates */
-
- void SetPixel ( Point where , unsigned long value )
- {
- Rect r ;
- GDHandle theGD ;
- char * ptr ;
- long rowBytes ;
- short bitsPerPixel ;
- PixMapHandle pmh ;
- Boolean oldMode ;
-
- r . left = where . h ;
- r . top = where . v ;
- r . right = r . left + 1 ;
- r . bottom = r . top + 1 ;
- theGD = GetMaxDevice ( & r ) ;
- if ( theGD ) {
- where . v -= ( * theGD ) -> gdRect . left ;
- where . h -= ( * theGD ) -> gdRect . top ;
- pmh = ( * theGD ) -> gdPMap ;
- rowBytes = ( ( * pmh ) -> rowBytes ) & 0x3fff ;
- ptr = ( char * ) ( * pmh ) -> baseAddr ;
- bitsPerPixel = ( * pmh ) -> pixelSize ;
- oldMode = true32b ;
- ptr += where . v * rowBytes ;
- SwapMMUMode ( & oldMode ) ;
- switch ( bitsPerPixel ) {
- case 1 :
- if ( value & 1 ) {
- ptr [ where . h >> 3 ] |= ( 128 >> ( where .
- h & 7 ) ) ;
- } else {
- ptr [ where . h >> 3 ] &= ~( 128 >> ( where .
- h & 7 ) ) ;
- }
- break ;
- case 2 :
- ptr [ where.h >> 2 ] &= ( 192 >> 2 * ( where.h & 3 )
- ) ;
- ptr [ where.h >> 2 ] |= ( value & 3 ) << 2 * ( 3 - ( where.h
- & 3 ) ) ;
- break ;
- case 4 :
- ptr [ where.h >> 1 ] &= ( where . h & 1 ) ? 0xf : 0xf0
- ;
- ptr [ where.h >> 1 ] |= ( value & 15 ) << 4 * ( 1 - (
- where.h & 1 ) ) ;
- break ;
- case 8 :
- ptr [ where.h ] = value ;
- break ;
- case 16 :
- ( ( unsigned short * ) ptr ) [ where . h ] = value
- ;
- break ;
- case 32 :
- ( ( unsigned long * ) ptr ) [ where . h ] = value
- ;
- break ;
- default :
- abort ( ) ; /* Should never get here */
- }
- SwapMMUMode ( & oldMode ) ;
- }
- }
-
- 5.12) Q: What (sprite) animation libraries are available for
- Macintosh?
-
- A: Several. All of these are object-oriented, and most are game-oriented,
- though they might be used for other purposes. Using one of these
- for about-box animations, as one of the authors suggests, is
- akin to using MacApp to write Hello, World. For more thorough
- uses, any one of these should be great. If you have anything
- to add, don't hesitate to contact the editor.
-
- SAT: Written in Pascal and available as PowerPC and 68k binary
- libraries, SAT is what you want if you're looking for simplicity
- and ease-of-programming. SAT is freeware (or shareware?) and
- the source is available if you can justify your reason for having
- it. Multiple sample games are included. At least four released
- games use SAT.
-
- SpriteWorld: Written in C, SpriteWorld is probably the best known
- of all the sprite libraries. While programming a game using
- SpriteWorld is more complex compared to doing it with SAT, full
- C source is included. Multiple sample games are included. Excellent
- for self-learning. Freeware, I believe.
-
- ACL: The Animation Class Library is written in C++. ACL is commercial,
- and a demo is available online. ACL is extremely flexible and
- strongly grounded in object-oriented design using C++.
-
- 3DGM: The only 3D animation library available for Macintosh of
- which I'm aware, 3DGM is distributed by the same people distributing
- ACL. Several demos are available online. Commercial.
-
- [feel free to send in more]
-
- *6* Text
- 6.1) Q: How do I get TextEdit to display more than 32k of text?
- A: You don't. Truly, it's not worth it. There's a call-for-call
- TextEdit replacement called TE32k which does > 32k text, and
- is available from any recent Info-Mac mirror. It doesn't do
- styled text, though.
-
- 6.2) Q: How do I get TextEdit to display more than 32k of __styled__
- text *and* embedded objects in the text (such as pictures)?
- WASTE (http://cirrus.sprl.umich.edu/waste), now at release 1.1,
- is a vast improvement over TextEdit. It does >32k styled text,
- retains compatibility with the TextEdit style scrap (which is
- used to store styled text in files such as SimpleText's, as well
- as in the clipboard), embedded objects within the text, such
- as pictures, intelligent cut-and- paste, built-in Drag Manager
- support, built-in Undo support, includes source code and is freeware.
- Really worth the download
- (ftp://ghost.dsi.unimi.it/pub2/papers/piovanel/).
-
-
- "But," you nervously stutter, "WASTE is in Pascal! What now?"
-
- Dan Crevier is maintaining a C port of WASTE
- (ftp://rhino.harvard.edu/pub/dan/).
-
- 6.3) Q: I'm too backwards to use WASTE 1.1. How do I include
- pictures in text using TextEdit?
-
- A: There's no really easy way (such as a TEAddPict() call), and
- it will be a nasty kludge if you do get it working, but if you
- can live with that, here's how to do it. I do recommend that
- you take a look at Q 6.2, above.
- Write an algorithm to get the position of a special marker character
- [Teach/SimpleText uses option-space] or text attribute that the
- user will insert wherever he wants a picture. Pass this position
- to a function similar to the one below.
-
- /*
- TEDrawPicture
- Draw a picture within TextEdit's text.
-
- input:
- pos - the position of the special character in the text
- where the
- user wants a picture.
- r - size of picture
-
- output:
- r - frame in which picture was drawn */
-
- void TEDrawPicture(short pos,PicHandle pic,Rect &r,TEHandle theTE)
- {
- Point bottomLeft; //I think TT/ST uses topleft
-
- bottomLeft = TEGetPoint(pos, theTE);
-
- r.right = bottomLeft.h + (r.right - r.left);
- r.top = bottomLeft.v - (r.bottom - r.top);
- r.left = bottomLeft.h;
- r.bottom = bottomLeft.v;
-
- DrawPicture(pic, &r);
- }
-
- I'll leave selection and clipboard as an exercise for the reader.
-
- Thereotically, it should be possible to kludge up TextEdit to
- the point where it would treat pictures as if they were actually
- letters (rather big letters, but letters just the same). That's
- what the width and word break hooks are for, after all. However,
- this would be a lot of Work, and I've never seen it done. One
- is lead to believe that it's less work to create an improved
- version of TextEdit from the ground up with picture support.
- WASTE 1.1, in fact, does this rather nicely.
-
- 6.4) Q: I have all this money, and I want to get rid of it. How
- do I edit more than 32k of styled text now?
-
- A: There are at least three solutions.
-
- 1) The Galaxy application framework (mailto:galaxy@visix.com)
- comes with a styled text editting engine which does more than
- 32k of text. It also happens to support cross-platform application
- development. Pricing starts at $10000.
-
- 2) DataPak is selling a cross-platform library called "PAIGE".
- It is written to be customizable to any extent, and you can
- do _anything_ in it (want quicktime movies that play and flow
- with the text while editting? Three pages of code; you can adapt
- their picture sample code.) Available for Mac, Windows & Never
- Trusted and Power Mac. Pricing at $5000 ($25000 for source code)
- - it might be cheaper if you talk to them. Customer support
- is reputed to be "lousy".
-
- 3) Or you could use WASTE 1.1 with it's embedded objects implementation
- (want quicktime movies that play and flow with the text while
- editing? One page of code, if that much.)
-
- 6.5) Q: How do I convert from a string to a floating point type?
-
- A: Once you've got an Str255, you want to call the routine StringToExtended
- to change the number into type extended80, which is the 80-bit
- floating point type. The nice thing about StringToExtended is
- that it even works in funky foreign language scripts like Chinese.
- To use the routine, you must pass it not only the Str255 that
- you want converted, but also the results of the StringToFormatRec
- routine and the GetIntlResourceTable routine. The documentation
- is generally difficult, so I'll describe the parameters and give
- you a code example below. Here's what you pass to StringToExtended:
-
- - source: Obviously the string representation of the number.
-
- - myFormatRec: This is simply the format that you expect the number
- to be. For example, if you wanted a positive integer with up
- to 3 decimal places, you would want the format to be "###".
- (The "#" symbol means a non-zero filled digit, whereas a "0"
- would mean zero filled.) If you wanted an floating point exponential
- notation with up to 2 digit integer portion, exactly 2 digit
- decimal portion, and exactly 1 digit after the "E", your format
- would be "##.00E+0". (Actually, in Canada, you folks might use
- a "," instead of a "." for the decimal point; if you do, then
- you would put the locally correct symbol in there.) In a format
- string, you can put the format for a positive value, a negative
- value, and 0 seperated by semicolons (e.g. "##.00E+0;-##.00E+0;0.00E+0").
-
- But myFormatRec is not the format string itself, but is an internal
- format that you get from calling StringToFormatRec. This is
- so you can store the format returned to you by StringToFormatRec
- and use it on different international systems. There is a nice
- editor for ResEdit for 'FMAT' resources that lets you type the
- format string and will call StringToFormatRec for you and create
- an 'FMAT' resource out of the result. Then you can load the
- 'FMAT' at run time and pass it to myFormatRec.
-
- - partsTable: The number parts table from the 'itl4' resource.
- If you are using System 7 or later, you call GetIntlResourceTable,
- asking it for the number parts table. You don't need to worry
- about HLock'ing itlHandle because StringToExtended doesn't move
- memory; just don't do anything between your call to GetIntlResourceTable
- and the StringToFormatRec routine. If you are using System 6,
- you need to perform the GetIntlResourceTable by hand. It's a
- few lines of code; left as an exercise to the reader.
-
- - x: The extended number to put the thing into.
-
- So, let's say you expect the user to enter a string containing
- up to 5 digits in the integer with a thousand marker between
- the 3rd and fourth digit, exactly two digits after the decimal,
- put it in parenthesis if it's negative, and have it just be "0.00"
- if it's 0. (I will use "." for the decimal and "," for the thousand
- marker. Here's the C code (passing in the source string):
-
- Handle itlHandle; /* The 'itl4' resource handle
- */
- long offset, length; /* Offset-length of parts table
- */
- NumFormatStringRec myFormatRec; /* Canonical format record */
- extended80 x; /* The number to put it into
- */
-
- GetIntlResourceTable (smCurrentScript, smNumberPartsTable,
- &itlHandle, &offset, &length);
- StringToFormatRec ("/p##,###.00;(##,###.00);0.00",
- (NumberParts *)(*itlHandle + offset),
- &myFormatRec);
- StringToExtended (source, &myFormatRec,
- (NumberParts *)(*itlHandle + offset),
- &x);
-
- If you saved a format record in a resource using the 'FMAT' editor
- (which is really the preferred way to do it), you would change
- the code to look like this:
-
-
- Handle itlHandle; /* The 'itl4' resource handle
- */
- long offset, length; /* Offset-length of parts
- table */
- NumFormatStringRec **myFormatRec; /* Canonical format resource
- */
- extended80 x; /* The number to put it into
- */
-
- myFormatRec = (NumFormatStringRec **)GetResource('FMAT', MY_FMAT);
- GetIntlResourceTable (smCurrentScript, smNumberPartsTable,
- &itlHandle, &offset, &length);
- StringToExtended (source, *myFormatRec,
- (NumberParts *)(*itlHandle + offset),
- &x);
-
- The StringToExtended routines will return a result that will
- tell you if there are any parsing errors. Error checking is
- also left as an exercise to the reader.
-
- Of course, the reverse of the process (using ExtendedToString)
- works very much the same way, passing the same sorts of parameters.
-
- *7* Communications and Networking
-
- 7.1) Q: How do I get at the serial ports?
-
- A: You call OpenDriver for the names "/p.AOut" and "/p.AIn" to
- get at the modem port, and "/p.BOut" and "/p.BIn" for the printer
- port. The function RAMSDOpen was designed for the original Mac
- with 128 kB of memory and 64 kB of ROM, and has been extinct
- for several years.
-
- However, many users use their serial ports for MIDI, LocalTalk,
- graphic tablets, or what have you and have installed an additional
- serial port card to get more ports. What you SHOULD do as a
- good application is to use the Comm Toolbox Resource Manager
- to search for serial resources; this requires that the Comms
- Toolbox is present (true on earlier System 6 with an INIT, on
- later System 6 and System 7 always, as well as on A/UX) and that
- you have initialized the comms resource manager. The exact code
- follows (adapted from Inside Mac Comms Toolbox):
-
-
- #include "CommResources.h"
- OSErr
- FindPorts ( Handle * portOutNames, Handle * portInNames, Handle
- * names,
- Handle * iconHandles )
- {
-
- OSErr ret = noErr ;
- short old = 0 ;
- CRMRec theCRMRec , * found ;
- CRMSerialRecord * serial ;
-
- * portOutNames = NewHandle ( 0L ) ;
- * portInNames = NewHandle ( 0L ) ;
- * names = NewHandle ( 0L ) ;
- * iconHandles = NewHandle ( 0L ) ;
- while ( ! ret ) {
- theCRMRec . crmDeviceType = crmSerialDevice ;
- theCRMRec . crmDeviceID = old ;
- found = ( CRMRec * ) CRMSearch ( ( QElementPtr ) & theCRMRec
- ) ;
- if ( found ) {
- serial = ( CRMSerialRecord * ) found -> crmAttributes
- ;
- old = found -> crmDeviceID ;
- PtrAndHand ( & serial -> outputDriverName , * portOutNames
- ,
- sizeof ( serial -> outputDriverName ) ) ;
- PtrAndHand ( & serial -> inputDriverName , * portInNames
- ,
- sizeof ( serial -> inputDriverName ) ) ;
- PtrAndHand ( & serial -> name , * names ,
- sizeof ( serial -> name ) ) ;
- PtrAndHand ( & serial -> deviceIcon , * iconHandles
- ,
- sizeof ( serial -> deviceIcon ) ) ;
- } else {
- break ;
- }
- }
- return err ;
- }
-
- This will create four handles with the driver names, device names
- and driver icon handles for all of the available serial devices.
- Then let the user choose with a pop-up menu or scrolling list,
- and save the choice in your settings file.
-
- You can use OpenDriver, SetReset, SetHShake, SetSetBuf, SerGetBuf
- and the other Serial Manager functions on these drivers. To
- write to the serial port, use FSWrite for synchronous writes
- that wait until all is written, or PBWrite asynchronously for
- queuing up data that is supposed to go out but you don't want
- to wait for it. At least once each time through your event loop,
- you should call SerGetBuf on the in driver reference number you
- got from OpenDriver, and call FSRead for that many bytes - neither
- more nor less.
-
- If you are REALLY interested in doing the right thing, you will
- use the Communications Toolbox Connection Manager instead; this
- will give you access to modems, direct lines, and networks of
- various kinds using the same API! Great for stuff like BBSes
- that may be on a network as well etc. The Comms Toolbox also
- provides modularized terminal emulation and file transfer tools,
- although the Apple-suplied VT102 tool is pretty lame, as is the
- VT102 mode of the VT320 tool. OTOH, the Comm Toolbox is being
- abandoned by Apple, to be replaced by Open Transport. (see below)
-
- 7.2) Q: Where is a Berkley sockets library for the Mac?
-
- A: There are some problems with that. MacTCP, the Mac Toolbox
- implementation of TCP/IP, doesn't have an API that looks at all
- like Berkley sockets. For instance, there is ONE paramater-block
- call to do a combined listen()/accept()/bind() - sort of. I
- have heard that there may be a socket library available by ftp
- from MIT but haven't seen it myself.
-
- There is also a pretty good C++ TCP implementation called GUSI
- which is easily handled, and it also is callable from C using
- the Berkley socket API. Apart from TCP, it also handles "standard"
- Mac network protocols such as ADSP. The big disadvantage is
- that it is currently only implemented for MPW. The ftp site
- is nic.switch.ch, software/mac/src/mpw_c.
-
- Don't forget to check out Apple's Open Transport architecture.
- Preliminary docs are available for ftp at seeding.apple.com.
- Open Transport will eventually replace MacTCP.
-
- Novell and Wollogong offer commercial socket-like libraries.
-
- 7.3) Q: Where do I find MacTCP?
-
- A: You can buy the MacTCP developers kit from APDA. It is also
- available on E T O, and if you want saner headers than those,
- try ftp to seeding.apple.com. MacTCP is included with System
- 7.5 and above.
-
- 7.4) Q: I'm trying to write to the serial port. It works fine
- on the following Machines, Quadra700, IIFX, Powerbook 170, Quadra
- 840av, but freezes on the Duo 230 and 280c.
-
- A: You need to call SerHShake. Otherwise you get screwed on
- some machines without a hardware handshaking cable because the
- port default to hardware handshaking.
-
- *8* IAC
-
- 8.1) Q: What are AppleEvents?
-
- A: AppleEvents are a level-5 network protocol. If you are not
- familiar with the ISO network stack, this means it's a way of
- structuring sessions between network entities (programs) that
- is not dependent on the underlying protocol (such as PPC or TCP/IP)
- Despite being a network protocol, they can be very useful on
- Macs that are not on a network. In short, they provide applications
- with a comprehensive way to send arbitrary structured data to
- other applications (or themselves) which receive the events through
- their main event loop.
-
- The AppleEvent Object Model is a way of looking at applications
- and the data they contain, and also a level-6 network protocol.
- You _can_ send AppleEvent Object Model data through AppleEvents
- (and the standard AppleEvents defined in the AppleEvent Registry
- use it) but you don't have to - unless you want to talk with
- other applications, of course, then the AEOM is a lingua franca.
-
- 8.2) Q: What are the four required AppleEvents?
-
- A: There are four events your application really must implement
- if you want to sell it: the kCoreEventClass class, kAEOpenApplication,
- kAEQuitApplication, kAEOpenDocuments and kAEPrintDocuments events
- IDs. When you support these events (or any AppleEvents) you
- will not get startup info through GetAppParams() anymore, unless
- you run under System 6 of course. The kAEOpenApplication event
- will be sent to you when the user double-clicks your app and
- it's not started yet. When receiving it, you can put up a new
- untitled window.
-
- kAEOpenDocuments is sent when the user double-clicks your apps
- documents. Note that if the first AppleEvent you receive is
- a kAEOpenDocuments event, the user started your app by double-clicking
- its documents.
-
- kAEPrintDocuments is sent when the user selects your documents
- and chooses "Print" in the Finder menu. If this is the first
- AppleEvent you receive, you should print the documents and then
- quit the application again; if you received a kAEOpenApplication
- or kAEOpenDocuments event before this, you should just print
- the documents and close them when you're done.
-
- kAEQuitApplication is sent to you when the user chooses "Shutdown"
- or "Restart" from the Apple Menu. You should ask the user whether
- he wants to save any unsaved changed documents, and then quit
- unless the user presses Cancel.
-
- Interestingly enough, you can use these four AppleEvents to send
- even to non-AE-aware applications, and the system will translate
- these events into fake menu selections for you.
-
- A good way of shutting down the Finder is to send it a Quit AppleEvent.
- You should send a Quit AppleEvent to File Sharing Extension
- before you shut down the Finder, though; the FSE is found by
- looking for a process with the creator 'hhgg'.
-
- 8.3) Q: Are there any limits or tradeoffs with AppleEvents?
-
- A: As always, more power means more responsibility.
-
- AppleEvents sent to applications on other Macs require authentification
- the first time they are sent. If the remote Mac allows Guests
- to link to programs, the INIT AutoGuest 2.0 might help (or the
- code solution that comes with it and you can build into your
- application)
-
- In the first version of the AppleEvent manager, there was a total
- 64K limit on the size of data and overhead. This limit has been
- lifted with the version of the AppleEvent manager that comes
- with AppleScript.
-
- AppleEvents require a lot of memory copying and handle resizing
- in their construction; this means that large AppleEvents may
- be slow in construction, especially when compared to a pure PPC
- Toolbox or ADSP/ASDSP link. The way around this is to use Jens
- Alfke's AEGizmos, available on the Developer CD, to create AppleEvents.
- AEGizmos are being integrated into System Software, so You Will
- be doing the right thing.
-
- You should use your own application signature as event class
- for AppleEvents you make up, in order not to collide with anybody
- else. Other than that, you are free to make your own events
- for your own needs, though supporting the required events and
- at least a subset of the Core event suite will buy you a lot
- of functinality from within AppleScript. Especially important
- are the Get Current Selection and Set Current Selection events
- (which are really Get/Set Data on the contents of the current
- selection of the application)
-
- The signature for your application SHOULD be registered with DTS
- (mailto:devsupport@applelink.apple.com) to avoid conflicts;
- this is done through e-mail and the form you use is located on
- the developer CDs and found on ftp.apple.com.
-
- 8.4) Q: How do AppleEvents interface with the Open Scripting
- Architecture (AppleScript)?
-
- A: AppleEvents are the meat and potatoes of OSA. If you support
- the AppleEvent Object Model from within your application, users
- can control you through an OSA-derived language, such as AppleScript.
-
- The first thing you should do is get ahold of Inside Mac: Interapplication
- Communication, and a copy of the AppleEvents Registry. The former
- tells you all you ever need to know about AppleEvents, while
- the latter is paramount for implementing the right standard events.
- If everybody use the standard events, dynamic data interchange
- between any applications will become sweet reality!
-
- Then there is the 'aete' resource which lets you put names on
- the events you support, so that users can "Open Terminology"
- on your application from within the Apple Script Editor and use
- the proper AppleScript commands in their scripts. The format
- of an aete resource is defined in Inside Macintosh: Interapplication
- Communication.
-
- 8.5) Q: Can I compile and run scripts from within my application?
-
- A: Yes, this is very simple. There are toolbox calls for reading
- scripts, compiling scripts, and executing scripts. (OSACompile,
- OSAExecute) These are all documented in Inside Mac: Interapplication
- Communication.
-
- 8.6) Q: Is this a good way of getting a macro language almost
- for free?
-
- A: "Good" is an understatement. Just let users write scripts,
- load them into menu items and go. Total systems integration
- in under a week, including adding support for the AEOM to your
- application.
-
- There is source code for an application called "MenuScripter"
- on the developer CD which shows you how to do an application
- with all of the menus being AppleScript scripts.
-
- 8.7) Q: Why do I get error -903 (noPortErr) when I try to send
- an Apple Event?
-
- A: Make sure the isHighLevelEventAware flag in your application's
- SIZE resource is set. The AE Manager won't allow you to send
- events if you're not able to receive them.
-
- 8.8) Q: Didn't I hear that ApplEvents are slow?
-
- A: Yes and no. Yes, they are slower than necessary in current
- systems. No, they don't inherently have to be slow, and this
- performance is being improved in Copland. But you can realize
- some Coplandish improvements right now by taking advantage of
- Jens Alfke's AEGizmos library, which is being rolled into Copland
- as one of the major speed improvements. CodeWarrior users have
- this library in a folder in the PowerPlant folder.
-
- *9* Standalone Code & Trap Patching
-
- 9.1) Q: How do I do code resources/extensions/external functions,
- much like HyperCard XCMDs only for my app/extension?
-
- A: The complete design process:
-
- Define a storage location for the plug-ins. For an application
- called Foo, use a folder called "Foo PlugIns / Modules / Tools
- / Etc", which your application checks for the existence of at
- startup, creating anew if necessary. The name of this plug-in
- folder should be in a 'STR#' resource for easy localization.
- HyperCard actually forced you to embed XCMDs and XFCNs inside
- user documents, but this led to duplicate XCMDs everywhere.
-
- Decide whether or not you're going to require the Code Fragment
- Manager. If you do, you sacrifice backward compatibility with
- most 68k Macs, but you will gain numerous programming advantages:
-
- You can call any exported function in a code fragment directly. You
- can take advantage of File Mapping on PowerMacs to reduce memory
- footprints. (Under System 7.x, this requires that the fragment
- be located in the data fork.) You can use SOM to implement C++-based
- interfaces.
-
- If you decide to support 68k Macs, define a resource type to
- hold your 68k plug-in exectuable code. To avoid runtime resource
- loading issues, you should avoid using 'CODE'. This still applies
- under the 68k Code Fragment Manager, although you can store the
- code in the data fork under that architecture.
-
- If you decide to support PowerPC code in seperate resources,
- repeat the above step.
-
- If you decide to use fat resources, ie have resources with both
- 68k and PPC code, all of the below discussion on 68k resources
- applies. If you want your code resource under PowerPC CFM to
- have a single entry point, most of the 68k discussion still applies.
- If you want to take full advantage of the CFM, you don't need
- to bother with selectors, dispatching, and the rest. See Inside
- Mac: PowerPC System Software.
-
- Decide whether you will allow multiple code resources per file.
- For example, Photoshop lets you bundle an import resource, an
- export resource, and a filter into the same file, each is its
- own resource type. It uses the resource name to tell the user,
- so each has its own name. Be aware that you can have multiple
- CodeFragments in a single data fork, but MPW is required at present.
-
- Decide on the user interface to plug-ins. Typically, this is
- answered best by asking "What will these plug-ins be used for?"
- Commonly, at program start-up, you scan the PlugIns folder and
- collect all the files of the correct types. Photoshop inserts
- the names of certain types of plug-ins into appropriate menus.
- Other types of Photoshop plug-ins do work "behind the scenes."
-
- Under Copland, you will be able to register notification requests
- which enable the file system to send messages to your application
- when a user moves files from/to specific folders, thus allowing
- the implementation of dynamic module addition/deletion. You
- should take this into account now in order that you need not
- worry about it when it happens.
-
- Use a Pascal-based calling convention to ensure maximum compatibility
- with all Mac compilers, something like:
-
- pascal OSErr MyCodeModule(ParamsBlock *inParams, Boolean doSomething);
-
- ParamsBlock is typically something like:
-
-
- typedef struct
- {
- long outVersion; // * version of interface used by
- plug-in
- long inVersion; // * version of interface used by
- program
- long inSelector; // * what to do with the data
- Handle inData; // * here's the data, do what you
- will with it
- long refCon; // * program ignores this; for internal
- plug-in use
- }ParamsBlock, *ParamsBlockPtr;
-
- outVersion is filled in by the plug-in on the init selector with
- the minimum version of the program that the plug-in can be used
- with. inVersion is the current version of the program, inSelector
- is a value which is used to differentiate operations. An "init"
- selector is a good idea, as is a Dispose selector, and have Init
- return an error or a refcon, which will be passed back to the
- plug-in on each call, so the plug-in can have some persistent
- storage. You should definately set the CurResFile to the plug-in's
- file while it is running, so it can easily get at any resources
- it needs.
-
- The actual call to the plug-in under 68k looks like:
-
-
- h = GetResource('PLUG', 1);
- HLock(h);
- xh = StripAddress(h);
- ((PlugInFunc) *xh)(kInit, callbacks, kInterfaceVer1, kProgVer1,
- 0, 0);
- HUnlock(h);
-
- The StripAddress is important if you want to work on Macs running
- under the 24-bit ROMs; if your app is running in 24bit mode,
- the resource handle may contain tag bits and you don't want strange
- things to happen if the code resource switches into 32bit mode
- (which QuickDraw may do, incidentally). Note that most post-1993
- Macs always run in 32-bit mode, so this is becoming less of a
- problem.
-
- This won't work properly under PowerPC unless the code resource
- is really just raw PowerPC machine code, with no surrounding
- code fragment stuff. See Inside Mac:PowerPC System Software
- for information on the proper use of Code Fragments.
-
- 9.2) Q: How do I fat-patch a trap (that is, how do I patch a
- trap with both 68k and PPC code)?
-
- A: Create a normal fat routine descriptor and pass it to SetToolTrapAddress()
- or SetOSTrapAddress in place of the normal procedure pointer.
-
- *10* Compatibility
-
- 10.1) Q: I see all these people call Gestalt without first checking
- whether it's implemented. Isn't that bad?
-
- A: No; Gestalt and a few other traps (the HXxx file manager traps,
- and FindFolder) are implemented using glue so they do the right
- thing even if the trap is not implemented.
-
- If you want to get rid of the glue, you can #define SystemSevenOrLater
- (and remember to recompile precompiled headers!) However, then
- you will be responsible for checking for these features before
- you use them.
-
- 10.2) Q: What more functions are implemented in glue?
-
- A: Wake Up and Smell the Glue!
-
- How often have you wished you could use that cool new ToolBox
- call, but didn't want to make your application System 7 dependent?
- Well, it might be that you *could* in fact have used the call.
- Several traps are implemented in glue, that is, much of their
- functionality is linked into your application and thus available
- even if you are running under an old System.
-
- FSOpen: Tries first OpenDF, then Open.
-
- HOpenResFile: Full functionality emulated if trap not available
-
-
- HCreateResFile: Full functionality emulated if trap not available
-
-
- FindFolder: Under System 6, understands the following values
- for folderType and returns the System Folder for all of them:
-
-
- kAppleMenuFolderType
-
- kControlPanelFolderType
-
- kExtensionFolderType
-
- kPreferencesFolderType
-
- kPrintMonitorDocsFolderType
-
- kStartupFolderType
-
- kSystemFolderType
-
- kTemporaryFolderType
-
- SysEnvirons: Full functionality emulated if trap not available
-
-
- NewGestalt: Returns an error if not implemented
-
- ReplaceGestalt: Returns an error if not implemented
-
- Gestalt: The following selectors are always implemented:
-
- vers mach sysv proc fpu
-
- qd kbd atlk ram lram
-
- 10.3) Q: I have to support System 6, don't I?
-
- A: It would be foolish to lock yourself out of the many benefits
- the System 7 API provides for software that you start to write
- now. Some of the System 6 and older things (likely SFGetFile
- and wdRefNums among others) will be phased out of the interfaces
- and lose support; especially on future platforms. Note: the
- major System Software release after Copland (System 8) is the
- one where this stuff is very likely to break. This gives you
- until ca. 1997 to remove old stuff, but you'll want to do it
- sooner to realize full performance advantages under Copland.
-
- The installed base of System 7 is larger than that of System
- 6; this is not surprising because Apple has been shipping System
- 7 for several years with all new machines, including everything
- from the Classic II on up. Another argument is that newer computer
- owners (having System 7) are much more likely to buy new software
- than old computer owners who have systems that already do what
- they want them to.
-
- The added work to support both System 6 and System 7 is significant;
- if you have the time and money you may want to do it, but only
- supporting System 6 and not System 7 is doomed to fail in the
- market of today.
-
- Some may call this position subjective; I call it business sense
- based on market demographics. A rule of thumb may be that if
- you target color machines only, you can just as well demand System
- 7 as well.
-
- Another thing to be aware of is that Copland will introduce new,
- more robust APIs for almost everything, including the Window
- Manager, Menu Manager, Resource Manager, and File Manager. At
- some point, if you still want to support System 6, you'll find
- yourself support three different Systems, with all the application
- bloat that one might expect.
-
- Note also that Apple no longer sells System 6.0.8, the very last
- version of System 6.
-
- 10.4) Q: Why does my application work on an SE with accellerator
- (or a Mac II or Quadra), but not on one without?
-
- A: Assuming you're not calling Color QuickDraw (which is not
- available on accellerated SEs), you most probably have an odd-aligned
- word access somewhere.
-
- The 68000 does not allow words or longwords to be read from odd
- addresses, while the 68020 and up relaxes this restriction (it
- still is slower than aligned-word access though)
-
- This may or may not crash depending on your compiler:
-
-
- struct foo {
- char c1 ;
- char c2 ;
- char c3 ;
- char c4 ;
- char c5 ;
- } bar ;
-
- long * x = ( long * ) & bar . c2 ;
- * x = 0x12345678 ; /* X is odd if compiler doesn't pad */
-
- This WILL crash on an SE/Plus/Classic/PB100:
-
-
- char foo [ 10 ] ;
-
- long * x = ( long * ) & foo [ 1 ] ;
- * x = 0x12345678 ;
-
- 10.5) Q: Why does my application work on a IIci and on early
- PowerMacs but not on a Quadra?
-
- A: Two reasons:
-
- 1) The Quadras 900 and 950 have special processors that handle
- the serial ports; if you write directly to the serial chips,
- you will crash (this goes for the IIfx as well)
-
- 2) The Quadras have 68040 processors, as have the Centrises.
- These processors have separate instruction and data caches (like
- the 68030) but they are larger (4K each) and unlike the 68030
- which is write-through data cached, the 68040 is copy-back data
- cached. This means that changes you make to "your code" aren't
- really changed all the time, since the changes may still be in
- the data cache and not written to memory when the CPU reads that
- part of memory into its I-cache. Even worse; that part might
- already have been read into the I-cache before you change it
- in the D-cache, meaning that writing out the D-cache will still
- not be enough. You need to flush both the caches when writing
- self-modifying code.
-
- Self-modifying code includes code that builds its own jump tables
- and code that decrypts itself and code that "stubs" MDEFs or
- WDEFs to jump back into the application code.
-
- You flush the cache using FlushDataCache() which is implemented
- if Gestalt says you have a 68020 or better processor (or if the
- _HwDispatch trap is implemented)
-
- The PowerMac 68k emulator used in all PowerMacs prior to the
- 9500 doesn't have the self-modifying cache problem (thereby being
- more compatible with old software than a Quadra!), but the dynamic
- recompiling emulator in the 9500 and beyond have the same restrictions
- as the 040's.
-
- 10.6) Q: Why does my application work on my Quadra but not on
- my accellerated SE?
-
- A: You're probably calling Color QuickDraw without first checking
- if it's available. The following machines do not have color
- QuickDraw in ROM nor RAM:
-
- Mac Plus, Mac SE, Mac Classic, Mac Luggable, PowerBook 100, Outbound
-
- 10.7) Q: I do check for color quickdraw, but crash nevertheless.
-
- A: _Gestalt lies under some versions of System 7; it says that
- non-color machines HAVE color QuickDraw when you test using the
- gestaltQuickdrawFeatures selector.
-
- Instead, check the gestaltQuickdrawVersion selector, if it returns
- >= gestalt8BitQuickdraw then you can safely use gestaltQuickdrawFeatures,
- else you only have b/w QuickDraw.
-
- 10.8) Q: What can I do now to prepare my code for Copland (System
- 8.0) (and beyond)?
-
- A: Just the stuff Apple's been telling us for years: Support
- OpenTransport. Thread your applications using the Thread Manager.
- Be fully 32-bit clean (of course). Don't patch traps. If you
- do patch traps, be aware that you will need to rewrite that code.
- Don’t use the Window Manager low-mem globals. Don't manipulate
- the GrayRgn. Use Sound Manager 3. Don't manipulate hardware
- directly. Rewrite extensions and control panels so that the
- code that actually provides the functionality is seperated from
- the code that installs or activates it. Rewrite DAs as applications.
- Almost everything in Copland is new or rewritten. Learn about
- the Collection Manager, first introduced with QuickDraw GX and
- documented in the QDGX Inside Mac books. The Collection Manager
- is used throughout the Copland Toolbox to provide robust, flexible,
- and standard dynamic array services, and seems to be the one
- API untouched by change in Copland.
-
- While you _might_ be able to get away with using MacTCP, Comm
- Toolbox, trap patching, low-mem global manipulation, and other
- nasty stuff in Copland, the performance of your app will be lacking,
- and it *will break* on system versions beyond Copland
- (http://www.info.apple.com/dev/geeks.html).
-
- You will not be able to get away with 32-bit dirtyness in Copland,
- and at least some of the hardware will be protected. Desk Accessories,
- Control Panels, and Extensions as we know them won't run under
- Copland.
-
- *11* Optional System Software
-
- *11.1* QuickTime
- 11.1.1) Q: I want to write a Amiga QuickTime player and need
- the PREC format details.
-
- A: Although the structure of QuickTime movies is well documented
- in Inside Mac: QuickTime, the inner workings of the Apple compression
- modules is a trade secret that Apple will only license to you
- at great cost. Perhaps it's time for a freeware, cross-platform
- QuickTime codec?
-
- *11.2* QuickDraw 3D
-
- 11.2.1) Q: Where do I start with QuickDraw 3D?
-
- A: Apple (http://www.info.apple.com/) maintains a web server
- devoted to QuickDraw 3D (http://qd3d.apple.com).
-
- *11.2* OpenDoc
-
- 11.2.1) Q: Tell me about OpenDoc, please?
-
- A: OpenDoc can be found at CILabs and Apple
- (http://www.info.apple.com/dev/du/intro_to_opendoc/iod0_index.html),
- and an OpenDoc-interest mailing list is maintained at CILabs
- for those who are interested enough.
-
- *12* Third-Party Solutions
-
- *12.1* Databases
-
- 12.1.1) Q: What are some royalty-free databases available for
- the Macintosh?
-
- A: These are commercial with no run-time licenses:
-
-
- Prograph CPX (mailto:sales@prograph.com) comes with a database
- that can do indexes and tables.
- CXBase Pro (mailto:tse.int@applelink.apple.com) is an engine
- that comes with source, does tables and indexes in one compound
- file.
- dtF (mailto:DTF.AMERICA@applelink.apple.com) is a relational
- database library.
-
- NeoAccess is an object-oriented database, where you can store
- objects and retrieve by field value; it handles inheritance as
- well. Comes as a demo on the CodeWarrior CD with an unlockable
- archive of the real thing.
-
- 12.1.2) Q: I need a robust Client/Server database library.
-
- A: Get the Macintosh Client/Server Database Development Summary
- (mailto:maccsdb@external.umass.edu), by Liam Breck. It covers
- software applicable to Macintosh (and cross-platform) client/server
- database development in three categories:
-
-
- Client application development tools
- Data access layers
- Database servers
-
- The eight page (20 Kbytes ASCII text) document includes explanations
- of the three categories and describes over 30 products. Its
- sources are vendors' product literature, industry periodicals,
- and discussions with users and vendors' tech support staff.
- It is purely informational and contains no propaganda, as the
- author is a neutral party.
-
- *12.2* Circumvention of Toolbox Limitations
-
- 12.2.1) Q: Help! The List Manager is driving me right up the
- wall! I want to throw it out and start over. What'r my options?
-
- A: The only commercially available non-framework List Manager
- replacement of which I'm aware is StoneTable
- (http://www.teleport.com/~stack), a commerical replacement library
- for the List Manager which provides many extensions including
- variable size columns/rows, column/row titles, different style/font/size/color
- per cell, sorting, edit in cell, and much more.
-
- TCL, PowerPlant, and MacApp (see section 1) all have their own
- integrated list management solutions.
-
- *13* Dessert
-
- 13.1) Q: Dessert?
-
- A: Honey Hill Farms Cookie Jar Frozen Yoghurt or Haagen-Dazs
- Raspberry & Cream Ice Cream.
-
- Hokey-Pokey icecream with chocolate sauce and (for those who
- like their brain food firmer) Almond and Double Chocolate CookieTime
- cookies!?
-
- President's Choice Decadent chocolate chip cookies straight out
- of the refrigerator with large quantities of milk.
-
- *14* Other Answers
-
- No FAQ is an island. The answer sheets/pages listed here cover
- in-depth topics only lightly touched upon in these electrons.
- Feel free to send in more!
-
- Language FAQs C++
- (http://www.cis.ohio-state.edu/hypertext/faq/bngusenet/comp/lang/c++/top.html) C
- (http://www.cis.ohio-state.edu/hypertext/faq/bngusenet/comp/lang/c/top.html)
-
- Graphics Programming FAQs comp.graphics.algorithms
- (http://www.cis.ohio-state.edu/hypertext/faq/usenet/graphics/algorithms-faq/faq.html)
- - good graphics programming pointers. Not very complete at this
- writing.
-
- Free Development Tools (http://www.europa.com/~sf/fdsm.html) Free/Shareware
- Development Tools FAQ, maintained by Brian Connors.
-
- The Literature of Mac Programming
- (http://www.pitt.edu:81/~nick/MacDev/Literature.html) A part
- of Nick DeMello's Mac Programming pages
- (http://www.pitt.edu:81/~nick/MacDev).
-
- Usenet Mac Game Programming book
- (http://www.best.com/~mxmora/c.s.m.g.p.b.0.html) Matt X. Mora
- is coordinating a virtual comp.sys.mac.programmer Game Programming
- book.
-
- Land O' Mac Geeks (http://dts.apple.com/geeks.html) DTS Mac programming
- page.
-
- Portable Parallel C++
- (http://www.extreme.indiana.edu/sage/pcxx_ug/pcxx_ug.html) PowerMacintosh
- programming at an affordable price. Who needs Java?
-
- *15* Contributors
-
- The public domain comp.sys.mac.programmer FAQ sheet was started
- by, and largely reflects the wisdom of, Jon Watte
- (mailto:h+@austin.metrowerks.com). Chris Thomas (mailto:ckt@best.com)
- succeeded him as content editor/caretaker in 1994, and usurped
- distribution in 1995.
-
- The following is a list of people who've contributed to the FAQ
- directly. If I've forgotten someone or you want a name corrected, please
- let me know (mailto:ckt@best.com).
-
-
- Brian Bechtel (mailto:blob@apple.com)
- Denis Birnie
- C. Ben Boyle (mailto:boyle@spacsun.rice.edu)
- Liam Breck
- Scott Bronson (mailto:urge@mcl.mcl.ucsb.edu)
- Jim Chan (mailto:jchan@bio-rad.com)
- Brian Connors (mailto:connorbd@cleo.bc.edu)
- Tim Converse (mailto:converse@cs.uchicago.edu)
- Chris (mailto:dagnon@cs.wisc.edu)
- Bob Hablutzel
- Julian Harris
- Bruce Hoult (mailto:Bruce@hoult.actrix.gen.nz)
- Peter Jensen (mailto:pjensen@netcom.com)
- Steve Jasik (mailto:macnosy@jasik.com)
- Jonathan Kimmitt (mailto:jrrk@camcon.co.uk)
- Scott Kleper (mailto:sjked@rit.edu)
- Jim Lloyd (mailto:jim@melongem.com)
- Matthias Neeracher (mailto:neeri@iis.ee.ethz.ch)
- David P. Oster (mailto:oster@netcom.com)
- Louis M. Pecora
- Marco Piovanelli (mailto:piovanel@dsi.unimi.it)
- Ingemar Ragnemalm (mailto:ingemar@lysator.liu.se)
- Pete Resnick (mailto:resnick@uiuc.edu)
- Phil Shapiro (mailto:phils@bedford.symantec.com)
- eric slosser (mailto:slosser@apple.com)
- M Sooriarachchi
- Bill (mailto:stack@teleport.com)
- Chris Thomas (mailto:ckt@best.com)
- Mark Valence (mailto:kurash@dartmouth.edu)
- Doug W. (mailto:dougw@as.arizona.edu)
- Jon Watte (mailto:h+@austin.metrowerks.com)
- Rick Zaccone (mailto:zaccone@bucknell.edu)
-
- This FAQ is public domain.
-
-